#!/usr/bin/env python3
###
# @Author: Logan.Li
# @Gitee: https://gitee.com/attacker
# @email: admin@attacker.club
# @Date: 2025-03-14 09:35:30
# @LastEditTime: 2025-03-14 09:35:35
# @Description: 华为云监控核心模块
###

import os
import json
import logging
from typing import Dict, List
from huaweicloud_sdk_core.auth.credentials import BasicCredentials
from huaweicloud_sdk_ces.v1.region.ces_region import CesRegion
from huaweicloud_sdk_ces.v1 import *

class HuaweiCloudMonitor:
    """华为云监控基类"""
    
    def __init__(self, config: Dict):
        """初始化
        
        Args:
            config: 配置信息，包含ak和region
        """
        self.config = config
        self.credentials = BasicCredentials(
            ak=config['access_key'],
            sk=config['secret_key']
        )
        
        # 初始化客户端
        self.client = CesClient.new_builder() \
            .with_credentials(self.credentials) \
            .with_region(CesRegion.value_of(config['region'])) \
            .build()
            
    def get_metric_data(self, namespace: str, metric_name: str, dimensions: List[Dict]) -> Dict:
        """获取监控数据
        
        Args:
            namespace: 命名空间
            metric_name: 指标名称
            dimensions: 维度列表
        """
        try:
            request = BatchListMetricDataRequest()
            request.body = {
                "metrics": [{
                    "namespace": namespace,
                    "metric_name": metric_name,
                    "dimensions": dimensions
                }]
            }
            response = self.client.batch_list_metric_data(request)
            return response.to_dict()
        except Exception as e:
            logging.error(f"获取监控数据失败: {e}")
            return {}
            
    def create_alarm_rule(self, rule_name: str, namespace: str, 
                         metric_name: str, dimensions: List[Dict],
                         threshold: float) -> None:
        """创建告警规则
        
        Args:
            rule_name: 规则名称
            namespace: 命名空间
            metric_name: 指标名称
            dimensions: 维度列表
            threshold: 阈值
        """
        try:
            request = CreateAlarmRequest()
            request.body = {
                "alarm_name": rule_name,
                "metric": {
                    "namespace": namespace,
                    "metric_name": metric_name,
                    "dimensions": dimensions
                },
                "condition": {
                    "comparison_operator": ">=",
                    "count": 3,
                    "filter": "average",
                    "period": 300,
                    "value": threshold
                },
                "alarm_enabled": True
            }
            
            self.client.create_alarm(request)
            logging.info(f"创建告警规则成功: {rule_name}")
        except Exception as e:
            logging.error(f"创建告警规则失败: {e}")
            
    def list_alarms(self, limit: int = 100) -> List[Dict]:
        """获取告警规则列表"""
        try:
            request = ListAlarmRulesRequest()
            request.limit = limit
            response = self.client.list_alarm_rules(request)
            return response.to_dict().get('alarm_rules', [])
        except Exception as e:
            logging.error(f"获取告警规则列表失败: {e}")
            return []
            
    def get_alarm_history(self, alarm_id: str) -> List[Dict]:
        """获取告警历史"""
        try:
            request = ListAlarmHistoriesRequest()
            request.alarm_id = alarm_id
            response = self.client.list_alarm_histories(request)
            return response.to_dict().get('alarm_histories', [])
        except Exception as e:
            logging.error(f"获取告警历史失败: {e}")
            return []
            
    def get_resource_groups(self) -> List[Dict]:
        """获取资源组列表"""
        try:
            request = ListResourceGroupRequest()
            response = self.client.list_resource_group(request)
            return response.to_dict().get('resource_groups', [])
        except Exception as e:
            logging.error(f"获取资源组列表失败: {e}")
            return []
            
    def aggregate_alarms(self, alarms: List[Dict]) -> Dict:
        """聚合告警信息
        
        Args:
            alarms: 告警列表
        """
        result = {
            'total': len(alarms),
            'critical': 0,
            'major': 0,
            'minor': 0,
            'top_instances': []
        }
        
        # 统计各级别告警数量
        for alarm in alarms:
            severity = alarm.get('severity', '').lower()
            if severity == 'critical':
                result['critical'] += 1
            elif severity == 'major':
                result['major'] += 1
            elif severity == 'minor':
                result['minor'] += 1
                
            # 收集异常实例信息
            if severity in ['critical', 'major']:
                instance_info = {
                    'name': alarm.get('alarm_name'),
                    'resource_id': alarm.get('resource_id'),
                    'metric': alarm.get('metric', {}).get('metric_name'),
                    'value': alarm.get('current_value'),
                    'threshold': alarm.get('threshold'),
                    'time': alarm.get('update_time')
                }
                result['top_instances'].append(instance_info)
                
        # 只保留最近的10个严重异常实例
        result['top_instances'] = sorted(
            result['top_instances'],
            key=lambda x: x['time'],
            reverse=True
        )[:10]
        
        return result
